﻿#include "Calculator.h"
#include "ui_calculator.h"
#include <iostream>
using namespace std;
#pragma execution_character_set("utf-8")

Calculator::Calculator(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Calculator)
{
    ui->setupUi(this);
}

Calculator::~Calculator()
{
    delete ui;
}

void Calculator::on_clear_clicked()
{
    ui->lineEdit->clear();
    equalPressFlag=0;
}

void Calculator::on_backspace_clicked()
{
    numberInit();
    ui->lineEdit->backspace();
}

void Calculator::on_btn_1_clicked()
{
    numberInit();
    ui->lineEdit->insert("1");
}

void Calculator::on_btn_2_clicked()
{
    numberInit();
    ui->lineEdit->insert("2");
}

void Calculator::on_btn_3_clicked()
{
    numberInit();
    ui->lineEdit->insert("3");
}

void Calculator::on_btn_4_clicked()
{
    numberInit();
    ui->lineEdit->insert("4");
}

void Calculator::on_btn_5_clicked()
{
    numberInit();
    ui->lineEdit->insert("5");
}

void Calculator::on_btn_6_clicked()
{
    numberInit();
    ui->lineEdit->insert("6");
}

void Calculator::on_btn_7_clicked()
{
    numberInit();
    ui->lineEdit->insert("7");
}

void Calculator::on_btn_8_clicked()
{
    numberInit();
    ui->lineEdit->insert("8");
}

void Calculator::on_btn_9_clicked()
{
    numberInit();
    ui->lineEdit->insert("9");
}

void Calculator::on_btn_0_clicked()
{
    numberInit();
    ui->lineEdit->insert("0");
}

void Calculator::on_point_clicked()
{
    numberInit();
    ui->lineEdit->insert(".");
}

void Calculator::on_plus_clicked()
{
    if(signInit())ui->lineEdit->insert("+");
}

void Calculator::on_subtract_clicked()
{
    if(signInit())ui->lineEdit->insert("-");
}

void Calculator::on_div_clicked()
{
    if(signInit())ui->lineEdit->insert("÷");
}

void Calculator::on_mul_clicked()
{
    if(signInit())ui->lineEdit->insert("×");
}

void Calculator::on_equal_clicked()
{
    signPressNum=0;
    equalPressFlag=1;     //将等号标志位设置为按下状态
    QString input=ui->lineEdit->text();     //获取输入框文本

    for(int i=0;i<input.size();++i)
    {
        //将所有显式或隐式的+号替换成空格，方便输入数字的分离
        //×号和÷号与数字地位相同，单独存储
        if(input[i]=="+")
        {
            input.replace(i,1," ");
            ++signPressNum;
        }else if(input[i]=="-"){
            input.replace(i,1," -");
            ++signPressNum;
            ++i;
        }else if (input[i]=="×") {
            input.replace(i,1," * ");
            ++signPressNum;
            i=i+2;
        }else if (input[i]=="÷") {
            input.replace(i,1," / ");
            ++signPressNum;
            i=i+2;
        }else {
            signPressNum=0;     //当输入数字时，运算符连续按下的次数清零
        }

        //当运算符被连续按下两次及以上时，向用户提供错误信息
        if(signPressNum>1)
        {
            ui->lineEdit->setText("ERROR:运算符连续");
            signPressNum=0;
            return;
        }
    }



    QList<QString> strCache=input.split(" ",QString::SkipEmptyParts);
    QList<double> doubleCache;

    for(int i=0;i<strCache.size();++i)
    {
        //当检测到*号或/号时，将该位置前一个元素和后一个元素取出来进行相关运算，丢弃这两个数，只储存运算所得结果
        if(strCache[i]=="*")
        {
            double nextCache=strCache[i+1].toDouble();
            doubleCache[doubleCache.size()-1]=doubleCache[doubleCache.size()-1]*nextCache;
            ++i;
        }else if (strCache[i]=="/") {
            double nextCache=strCache[i+1].toDouble();
            if(nextCache==0)
            {
                ui->lineEdit->setText("ERROR:除数不能为0");     //除数为0时，向用户提供错误信息
                return;
            }
            doubleCache[doubleCache.size()-1]=doubleCache[doubleCache.size()-1]/nextCache;
            ++i;
        }else {
            doubleCache<<strCache[i].toDouble();     //检测到数字时，存储起来
        }
    }

    double result=0;
    for(int i=0;i<doubleCache.size();++i)
    {
        result=(double)result+doubleCache[i];     //将存储的全部数字进行相加
    }

    ui->lineEdit->setText(QString::number(result));     //输出结果
}

void Calculator::numberInit()
{
    QString str=ui->lineEdit->text();

    //当等号的状态为被按下时，或者，输入框报错误信息时，若输入数字会清空输入框，再插入该数字
    if((equalPressFlag==1)||(str.contains("ERROR")))
    {
        ui->lineEdit->clear();
        equalPressFlag=0;
    }
}

int Calculator::signInit()
{
    equalPressFlag=0;
    QString str=ui->lineEdit->text();

    //输入框报错误信息时，按下任意运算符都会清空输入框
    if(str.contains("ERROR"))
    {
        ui->lineEdit->clear();
        return 0;
    }
    return 1;
}


